package net.lzzy.practices.services;

import net.lzzy.practices.constants.Messages;
import net.lzzy.practices.entities.Chapter;
import net.lzzy.practices.entities.Option;
import net.lzzy.practices.entities.Question;
import net.lzzy.practices.repositories.ChapterRepository;
import net.lzzy.practices.repositories.OptionRepository;
import net.lzzy.practices.repositories.QuestionRepository;
import net.lzzy.practices.utils.AuthUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.UUID;

/**
 * @author liaodcc on 2022/6/1 15:54.
 */
@Service
public class QuestionServiceImpl implements QuestionService{
    private final QuestionRepository repository;
    private final ChapterRepository cRepository;
    private final OptionRepository oRepository;

    @Autowired
    public QuestionServiceImpl(QuestionRepository repository, ChapterRepository cRepository, OptionRepository oRepository) {
        this.repository = repository;
        this.cRepository = cRepository;
        this.oRepository = oRepository;
    }

    @Override
    public List<Question> get(UUID chapterId) {
        return repository.findQuestionsByChapterIdOrderByOrdinal(chapterId);
    }

    @Override
    public Question add(UUID chapterId, Question question, String token) {
        Chapter chapter = cRepository.findById(chapterId).orElse(null);
        if (chapter == null){
            return null;
        }
        UUID teacherId = chapter.getCourse().getTeacher().getId();
        if (AuthUtils.invalid(teacherId,token)){
            return null;
        }
        question.setChapter(chapter);
        return repository.save(question);
    }

    @Override
    public Question update(UUID id, Question question, String token) {
        Question old = checkQuestion(id, token);
        if (old == null) {return null;}
        old.setAnalysis(question.getAnalysis());
        old.setContent(question.getContent());
        old.setOrdinal(question.getOrdinal());
        old.setType(question.getType());
        return repository.save(old);
    }

    private Question checkQuestion(UUID id, String token) {
        Question old = getById(id);
        if (old == null){
            return null;
        }
        UUID teacherId = old.getChapter().getCourse().getTeacher().getId();
        if (AuthUtils.invalid(teacherId, token)){
            return null;
        }
        return old;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Messages remove(UUID id, String token) {
        Question old =getById(id);
        if (old == null){
            return Messages.WRONG_ID;
        }
        UUID teacherId = old.getChapter().getCourse().getTeacher().getId();
        if (AuthUtils.invalid(teacherId,token)){
            return Messages.NO_PERMISSION;
        }
        oRepository.deleteAll(old.getOptions());
        repository.delete(old);
        return Messages.SUCCESS;
    }

    @Override
    public Question addOption(UUID questionId, Option option, String token) {
        Question question = checkQuestion(questionId,token);
        if (question == null){
            return null;
        }
        option.setQuestion(question);
        oRepository.save(option);
        return getById(questionId);
    }

    @Override
    public Question removeOption(UUID id, String token) {
        Option option = oRepository.findById(id).orElse(null);
        if (option == null){
            return null;
        }
        UUID questionId = option.getQuestion().getId();
        UUID teacherId = option.getQuestion().getChapter().getCourse().getTeacher().getId();
        if (AuthUtils.invalid(teacherId,token)){
            return null;
        }
        oRepository.delete(option);
        return getById(questionId);
    }

    @Override
    public Question getById(UUID id) {
        return repository.findById(id).orElse(null);
    }

    @Override
    public Integer countBy(UUID chapterId) {
        return repository.countAllByChapterId(chapterId);
    }
}
